#pragma 
#include "Log.hpp"
#include "InetAdrr.hpp"
#include <list>
#include <mutex>

using namespace LogModule;
//观察者模式
class UseStrategy
{
public:
    virtual ~UseStrategy() = default; //基类重写析构函数, 多态
    virtual void SendTo(int shockfd,const std::string& message) = 0;
    virtual bool operator==(InetAddr& addr) = 0;
    virtual  std::string Id()  = 0;
};

class User : public UseStrategy
{
public:
    User(const InetAddr& inaddr) 
        :_inaddr(inaddr)
    {}
    void SendTo(int shockfd,const std::string& message)
    {
        ssize_t n = ::sendto(shockfd,message.c_str(),message.size(),0,_inaddr.NetAddr(),_inaddr.NetAddrLen());
        (void)n;
    }

    bool operator==(InetAddr& addr)
    {
        return _inaddr.Ip() == addr.Ip() && _inaddr.Port() == addr.Port();
    }

    std::string Id() 
    {
        return _inaddr.Addr();
    }
    ~User() {}

private:
    InetAddr _inaddr;
};

class UserManager
{   
public:
    UserManager() {};

    void AddUser(InetAddr& in)
    {
        for (auto user:_online_user)
        {
            if (*user == in)
            {
                LOG(LogLevel::INFO) << in.Addr() << "用户已经存在";
                return;
            }
        }
        _online_user.push_back(std::make_shared<User>(in));
        LOG(LogLevel::INFO) << in.Addr() << "添加成功!!!!";
        Print();
    }
    void Print()
    {
        for (auto user_ptr : _online_user)
        {
            LOG(LogLevel::DEBUG) << "在线用户: " << user_ptr->Id();
        }
    }
    void DelteteUser()
    {
        
    }

    void route(int shockfd,const std::string& message)
    {
        std::unique_lock<std::mutex> _lock(_mtx);
        for (auto user_ptr : _online_user)
        {
            user_ptr->SendTo(shockfd,message);
        }
        Print();
    }

    ~UserManager(){};
private:
    std::list<std::shared_ptr<UseStrategy>> _online_user;
    std::mutex _mtx;
};

